﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace XiDainChangAn.OA.Common
{
    public delegate void WriteLogDel(string str);//定义一个委托来写日志
    public class LogHelper
    {
        //1，创建一个静态的队列，用来存储异常信息
        public static Queue<string> ExceptionStringQueue = new Queue<string>();

        #region MyRegion
        //方法1  利用“委托”的观察者模式
        // public static WriteLogDel WriteLogDelFuc; 
        #endregion

        //2，使用原始方法来实现观察者模式
        public static List<ILogWriter> LogWriteList = new List<ILogWriter>();

        static LogHelper()
        {
            #region MyRegion
            //方法1 利用“委托” 的观察者模式
            // WriteLogDelFuc += WriteLogToFile;
            //WriteLogDelFuc += WriteLogToMongodb; 
            #endregion

            //2，使用原始方法来实现观察者模式
            //LogWriteList.Add(new TextFileWriter());
            //LogWriteList.Add(new SqlServerWriter());
            LogWriteList.Add(new Log4NetWriter());


            //从队列中获取错误消息写到日志文件里去
            ThreadPool.QueueUserWorkItem(o =>
            {
                while (true)
                {
                    lock (ExceptionStringQueue)
                    {
                        if (ExceptionStringQueue.Count > 0)
                        {
                            string errorStr = ExceptionStringQueue.Dequeue();//出队列

                            //把异常信息写到（1）日志文件里面去 （2）数据库里面去


                            #region MyRegion
                            //执行委托方法，把异常信息写到委托里面去
                            //WriteLogDelFuc(errorStr);//调用一下委托就ok了 利用观察者模式 
                            #endregion

                            foreach (var item in LogWriteList)
                            {
                                item.WriterLogInfo(errorStr);
                            }

                            //log4net：已经帮助我们处理好了观察者模式
                        }
                        else
                        {
                            Thread.Sleep(30);//让线程睡30毫秒
                        }
                    } 
                }
            });
        }

        #region 方法1 利用委托的观察者模式

        #region 01，把错误信息写到日志文件中去+static void WriteLogToFile(string text)
        /// <summary>
        /// 把错误信息写到日志文件中去
        /// </summary>
        /// <param name="text"></param>
        public static void WriteLogToFile(string text)
        {
            //
        }
        #endregion

        #region 02，把错误信息写到Monbodb中去+static void WriteLogToMongodb(string text)
        /// <summary>
        /// 把错误信息写到Mongodb中去
        /// </summary>
        /// <param name="text"></param>
        public static void WriteLogToMongodb(string text)
        {
            //
        }
        #endregion


        #endregion


        public static void WriteLog(string exceptionText)
        {
            lock (ExceptionStringQueue)//将队列“锁着”，防止出现多线程操作的问题
            {
                ExceptionStringQueue.Enqueue(exceptionText);//将错误信息入队
            }
        }
    }
}
